// GeometricElement.java
// by Alexandre Martins, 2013
// MAC 5857 - Prof. Leonidas

package example.ilm.model;

import ilm.framework.assignment.model.DomainObject;
import example.ilm.gui.Polygon2D;

import java.awt.geom.Point2D;
import java.awt.geom.Point2D.Double;
import java.awt.geom.AffineTransform;
import java.awt.Color;
import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;

public abstract class GeometricElement extends DomainObject {

    /**
     * my data
     */
    protected Point2D position;
    protected List vertices;
    protected int highlightedVertex;
    protected boolean dragged;

    /**
     * constructor
     */
    static private int idCounter = 0;
    public GeometricElement(String elementName) {
        super((elementName + "[" + (++idCounter) + "]"), "a " + elementName);
        position = new Point2D.Double(0.0, 0.0);
        vertices = new ArrayList();
        unsetHighlightedVertex();
        drop();
    }

    // ---------- get/set -------------
    public Point2D getPosition() { return position; }
    public void setPosition(Point2D p) { position = new Point2D.Double(p.getX(), p.getY()); }
    public void setPosition(double x, double y) { position = new Point2D.Double(x, y); }

    public List getVertices() { return vertices; }
    public int getNumberOfVertices() { return vertices.size(); }

    public void unsetHighlightedVertex() { highlightedVertex = -1; }
    public void setHighlightedVertex(int vertexId) { highlightedVertex = vertexId; }
    public int getHighlightedVertex() { return highlightedVertex; }
    public boolean gotHighlightedVertex() { return highlightedVertex >= 0; }
    
    public void drag() { dragged = true; }
    public void drop() { dragged = false; }
    public boolean isBeingDragged() { return dragged; }
    // ---------- get/set -------------

    /**
     * verifica se um ponto esta' dentro do objeto
     */
    public boolean contains(Point2D p) {
        return false;
    }

    /**
     * pega os vertices ja transformados (transf. afim)
     */
    public List getTransformedVertices() {
        AffineTransform t = new AffineTransform();
        t.setToIdentity();
        t.translate(this.getPosition().getX(), this.getPosition().getY());

        List transformedVertices = new ArrayList();
        Iterator it = getVertices().iterator();
        while(it.hasNext()) {
            Point2D p = (Point2D)(it.next());
            Point2D q = t.transform(p, null);
            transformedVertices.add(q);
        }

        return transformedVertices;
    }

    /**
     * Comparison between two ObjectSquares
     */
    public boolean equals(DomainObject o) {
        GeometricElement obj = (GeometricElement)o;
        return (obj.getName().equals(getName()));
    }

    /**
     * Convert this object to a XML String, placing the fields between the
     * fields' names.
     */
    public String toString() {
        return "" + 
            "<geometricelement>" + 
                "<name>" + getName() + "</name>" + 
                "<description>" + getDescription() + "</description>" + 
                "<position>" +
                    positionToString() +
                "</position>" + 
                "<vertices>" +
                    verticesToString() +
                "</vertices>" +
            "</geometricelement>" +
        "";
    }

    /**
     * converts the list of vertices to a XML string
     */
    protected String verticesToString() {
        String vrt = "";
        Iterator it = vertices.iterator();
        while(it.hasNext()) {
            Point2D v = (Point2D)it.next();
            vrt += "" +
                     "<vertex>" + 
                         "<x>" + v.getX() + "</x>" + 
                         "<y>" + v.getY() + "</y>" + 
                     "</vertex>" + 
                   "";
        }
        return vrt;
    }

    /**
     * converts the position to a XML string
     */
    protected String positionToString() {
        return "" + 
            "<x>" + position.getX() + "</x>" +
            "<y>" + position.getY() + "</y>" +
        "";
    }
}
